# -*- coding: utf-8 -*-

"""剑指 Offer 14- II. 剪绳子 II
给你一根长度为 n 的绳子，请把绳子剪成整数长度的 m 段（m、n都是整数，n>1并且m>1），每段绳子的长度记为 k[0],k[1]...k[m - 1] 。
请问 k[0]*k[1]*...*k[m - 1] 可能的最大乘积是多少？例如，当绳子的长度是8时，我们把它剪成长度分别为2、3、3的三段，此时得到的最大乘积是18。
答案需要取模 1e9+7（1000000007），如计算初始结果为：1000000008，请返回 1。

示例 1：
输入: 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1

示例 2:
输入: 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36

提示：
2 <= n <= 1000
"""

class Solution:
    """总长10节的绳子，剪乘最大值
    max(
        max(最后1节 * 前面9节的剪乘最大值，最后1节 * 前面9节)
        max(最后2节 * 前面8节的剪乘最大值，最后2节 * 前面8节)
        max(最后3节 * 前面7节的剪乘最大值，最后3节 * 前面7节)
        ...
        max(最后9节 * 前面1节的剪乘最大值，最后9节 * 前面1节)
    )
    这似乎是动态规划，为了节省计算步骤，可以用缓存来进行空间换时间，缓存x节的剪乘最大值
    """
    def cuttingRope(self, n: int) -> int:
        cache = {}

        def do(x):
            if x in cache.keys():
                return cache[x]

            if x == 1:
                return 1
            
            max_multi = float('-inf')

            a = 1
            while a < x:
                max_multi = max(max_multi, a * do(x-a), a * (x-a))
                a += 1

            if x not in cache:
                cache[x] = max_multi

            return max_multi

        return do(n) % 1000000007


if __name__ == '__main__':
    print(Solution().cuttingRope(100))
